<template>
  <div>
    <el-form ref="form" :model="form" :rules="rules" size="mini">
      <el-form-item label="检查阶段" prop="problemType" key="problemType" v-if="isDelivery">
        <el-select v-model="form.problemType" placeholder="请选择检查阶段" style="width: 100%">
          <el-option v-for="item in problemTypeList" :key="item.value" :label="item.label" :value="item.value" />
        </el-select>
      </el-form-item>
      <el-form-item label="检查项" prop="chkitemCode">
        <el-select v-model="form.chkitemCode" placeholder="请选择检查项" :loading="firChkLoading" style="width: 100%" @change="onChangeChkitemCode">
          <el-option v-for="item in firChkList" :key="item.chkitemCode" :label="item.chkitemName" :value="item.chkitemCode" />
        </el-select>
      </el-form-item>
      <el-form-item label="验收标准" prop="standardId">
        <treeselect
          v-model="form.standardId"
          :options="categoryTree"
          :normalizer="categoryNormalizer"
          :load-options="lazyLoadStandardList"
          disable-branch-nodes
          placeholder="请选择验收标准"
          loading-text="加载中"
          :no-options-text="showStandardNoOptionsText"
          no-children-text="无子项"
          retry-text="重试"
          @select="onChangeStandardId"
        >
          <span slot="option-label" slot-scope="{ node, labelClassName }" :class="labelClassName" :title="node.label">
            {{ node.label }}
          </span>
        </treeselect>
      </el-form-item>
      <el-form-item label="问题房间" prop="positionId" key="positionId" :rules="isYfyy ? rules.positionId : []" v-if="isDelivery">
        <treeselect
          v-model="form.positionId"
          :options="buildingTree"
          :normalizer="buildingNormalizer"
          :load-options="lazyLoadRoomTree"
          disable-branch-nodes
          placeholder="请选择问题房间"
          loading-text="加载中"
          no-options-text="暂无数据"
          no-children-text="无子项"
          retry-text="重试"
          @select="onChangePositionId"
        >
          <div slot="value-label" slot-scope="{ node }">{{ node.raw.fnumber || node.raw.fnameL2 }}</div>
        </treeselect>
      </el-form-item>
      <el-form-item label="问题部位" prop="spaceId" key="spaceId" v-if="isDelivery">
        <treeselect v-model="form.spaceId" :options="spaceTree" :normalizer="spaceNormalizer" disable-branch-nodes placeholder="请选择问题部位" @select="onChangeSpaceId" />
      </el-form-item>
      <el-form-item label="违反数" prop="violateNum">
        <div class="el-input-group el-input-group--prepend el-input-group--append">
          <div class="el-input-group__prepend" style="padding: 0 10px">违反</div>
          <el-input-number v-model="form.violateNum" :min="1" :max="1e8" :precision="0" :controls="false" style="width: 100%" />
          <div class="el-input-group__append" style="padding: 0 10px">处</div>
        </div>
      </el-form-item>
      <el-form-item label="问题附件">
        <br>
        <div class="pic-list">
          <template v-if="picList.length">
            <div class="item" v-for="(item, index) in picList" :key="index" @click="previewPic(item)">
              <el-image class="img g-img-placeholder" :src="item.url" fit="cover" />
            </div>
          </template>
          <div class="item" @click="openSelectFileList">
            <i class="el-icon-plus" />
          </div>
        </div>
      </el-form-item>
      <el-form-item label="问题描述" prop="description">
        <el-input v-model="form.description" type="textarea" placeholder="请输入内容" :maxlength="255" />
      </el-form-item>
    </el-form>

    <SelectFileList ref="SelectFileList" multiple @ok="onSelectFileList" />
    <el-image ref="previewRef" class="hide" :src="previewSrc" :preview-src-list="previewSrcList" />
  </div>
</template>
<script>
// 问题录入
import Treeselect, { LOAD_CHILDREN_OPTIONS } from '@riophae/vue-treeselect'
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
import { flatList2tree, removeEmptyArray } from '@/utils'
import { EVAL_CHKITEM_CODE as CHK_CODE } from '@/utils/baseData'
import { buildingTreeWithRoom } from '@/api/baseManage/buildingManage'
import { planRoom } from '@/api/baseManage/houseManage'
import { listCheckStandard } from '@/api/qualityManage/cq'
import { listNextLevel, getCategory, getRoomspace } from '@/api/checkScore/cqEval'
import SelectFileList from './SelectFileList'
// 检查阶段。仅交付时展示，其他为默认值 NORMAL
const problemTypeList = [
  { label: '初验', value: 'FIRSTCHECK' },
  { label: '终验', value: 'FINALCHECK' }
]
export default {
  components: { Treeselect, SelectFileList },
  data() {
    return {
      problemTypeList,
      form: {
        // evalProblemId: '',
        // prjchkId: '',
        // projectId: '',
        // chkitemType: '',
        problemType: '',
        chkitemCode: '',
        versionCode:'',
        evalCategoryId: '',
        evalCategoryName: '',
        standardId: null,
        positionId: null,
        positionName: '',
        spaceId: null,
        spaceName: '',
        violateNum: null,
        description: ''
      },
      rules: {
        problemType: [{ required: true, message: '请选择检查阶段' }],
        chkitemCode: [{ required: true, message: '请选择检查项' }],
        standardId: [{ required: true, message: '请选择验收标准' }],
        positionId: [{ required: true, message: '请选择问题房间' }]
      },
      prjchkId: '',
      projectId: '',
      versionCode:'',
      chkitemType: '', // 检查项分类
      firChkList: [], // 一级检查项
      firChkLoading: false,
      categoryLoading: false,
      categoryTree: [],
      buildingLoading: false,
      buildingTree: [],
      spaceLoading: false,
      spaceTree: [],
      picList: [],
      previewSrcList: [],
      previewSrc: ''
    }
  },
  computed: {
    isDelivery() {
      // 是否为交付
      return this.chkitemType === CHK_CODE.DELIVERY
    },
    isYfyy() {
      // 是否为一房一验
      return this.form.chkitemCode === CHK_CODE.JF_YFYY
    },
    showStandardNoOptionsText() {
      if (this.categoryLoading) return '加载中'
      const chkCodeMsg = this.form.chkitemCode ? '' : '（请先选择检查项）'
      return `暂无数据${chkCodeMsg}`
    }
  },
  methods: {
    init({ prjchkId, projectId, chkitemType,versionCode }) {
      this.reset()
      this.prjchkId = prjchkId
      this.projectId = projectId
      this.chkitemType = chkitemType
      this.versionCode = versionCode
      this.getFirChkList()
      this.getBuildingTree()
      this.getSpaceTree()
    },
    reset() {
      this.resetFields()
      this.form.problemType = ''
      this.categoryLoading = false
      this.categoryTree = []
      this.spaceLoading = false
      this.spaceTree = []
      this.picList = []
      this.previewSrcList = []
      this.previewSrc = ''
    },
    resetFields() {
      const { problemType } = this.form
      this.form = {
        problemType: '',
        chkitemCode: '',
        evalCategoryId: '',
        evalCategoryName: '',
        standardId: null,
        positionId: null,
        positionName: '',
        spaceId: null,
        spaceName: '',
        violateNum: null,
        description: ''
      }
      this.categoryTree = []
      this.picList = []
      this.$refs.form.resetFields()

      // 交付的检查阶段不重置
      if (this.isDelivery) this.form.problemType = problemType
    },
    async getFirChkList() {
      this.firChkLoading = true
      const res = await listNextLevel({ chkitemCode: this.chkitemType,versionCode: this.versionCode  }).catch(() => false)
      this.firChkLoading = false
      if (res === false) return (this.firChkList = [])
      this.firChkList = res.data || []
    },
    onChangeChkitemCode(value) {
      this.form.evalCategoryId = ''
      this.form.evalCategoryName = ''
      this.form.standardId = null
      this.categoryTree = []
      this.getCategoryTree()
    },
    categoryNormalizer(node) {
      // if (!node.children?.length) delete node.children
      return { id: node.value, label: node.label, children: node.children }
    },
    async getCategoryTree() {
      const { chkitemCode } = this.form
      if (!chkitemCode) return (this.categoryTree = [])

      const opt = { chkitemType: this.chkitemType, chkitemCode }
      this.categoryLoading = true
      const res = await getCategory(opt).catch(() => false)
      this.categoryLoading = false
      if (res === false) return (this.categoryTree = [])

      let data = res.data || []
      data.map(i => {
        i.value = i.evalCategoryId
        i.label = i.evalCategoryName
      })
      data = flatList2tree(data, { id: 'evalCategoryId' })
      // children 设为 null 用于触发树形懒加载
      const recursion = list => list.map(i => (i.children?.length ? recursion(i.children) : (i.children = null)))
      recursion(data)

      this.categoryTree = data
    },
    async lazyLoadStandardList({ action, parentNode, callback }) {
      const item = parentNode || {}
      if (action !== LOAD_CHILDREN_OPTIONS) return callback()
      if (!item.evalCategoryId) return callback()

      const opt = { chkitemType: this.chkitemType, evalCategoryId: item.evalCategoryId }
      const res = await listCheckStandard(opt).catch(() => false)
      if (res === false) return callback(new Error('加载失败'))

      const data = res.data || []
      if (!data.length) {
        item.children = []
        return callback()
      }
      data.map(i => {
        i.value = i.standardId
        i.label = i.content
        i.evalCategoryName = item.evalCategoryName
        i.isLeaf = true
      })
      item.children = data
      callback()
    },
    onChangeStandardId(item = {}) {
      this.$refs.form.clearValidate('standardId')
      this.form.evalCategoryId = item?.evalCategoryId || ''
      this.form.evalCategoryName = item?.evalCategoryName || ''
    },
    buildingNormalizer(node) {
      // if (!node.children?.length) node.children = null
      return { id: node.fid, label: node.fnameL2, children: node.children }
    },
    async getBuildingTree() {
      // 获取楼栋+单元树
      const opt = { cfcurprojectid: this.projectId }
      this.buildingLoading = true
      const res = await buildingTreeWithRoom(opt).catch(() => false)
      this.buildingLoading = false
      if (res === false) return (this.buildingTree = [])

      const data = res.data || []
      // children 设为 null 用于触发树形懒加载
      const recursion = list => list.map(i => (i.children?.length ? recursion(i.children) : (i.children = null)))
      recursion(data)

      this.buildingTree = data
    },
    async lazyLoadRoomTree({ action, parentNode, callback }) {
      const item = parentNode || {}
      if (action !== LOAD_CHILDREN_OPTIONS) return callback()
      if (!['building', 'unit'].includes(item.type)) return callback()

      const opt = item.type === 'building' ? { fbuildingid: item.fid } : { fbuildingid: item.fbuildingid, fbuildunitid: item.fid }
      const res = await planRoom(opt).catch(() => false)
      if (res === false) return callback(new Error('加载失败'))

      const data = res.data || {}
      // 当前楼栋或单元下无楼层
      if (!data.floorArr?.length) {
        item.children = []
        return callback()
      }

      const unitArr = data.unitArr || []
      const tableRoom = data.table || []
      const floors = data.floorArr.map(fitem => {
        const children = []
        tableRoom.map(roomArr => {
          if (!roomArr?.length) return

          if (!unitArr.length) {
            if (roomArr?.ffloor !== fitem) return
            roomArr.fnameL2 = roomArr.fdisplayname
            roomArr.type = 'room'
            roomArr.isLeaf = true
            children.push(roomArr)
            return
          }

          roomArr.map(room => {
            if (room?.ffloor !== fitem) return
            room.fnameL2 = room.fdisplayname
            room.type = 'room'
            room.isLeaf = true
            children.push(room)
          })
        })
        return { fid: fitem + '', fnameL2: fitem + 'F', type: 'floor', cfloor: fitem, children }
      })

      item.children = floors
      callback()
    },
    onChangePositionId(item = {}) {
      this.form.positionName = item.fnumber || item.fnameL2
      if (this.isDelivery) this.$refs.form.clearValidate('positionId')
    },
    spaceNormalizer(node) {
      if (!node.children?.length) delete node.children
      return { id: node.spaceId, label: node.spaceName, children: node.children }
    },
    async getSpaceTree() {
      this.spaceLoading = true
      const res = await getRoomspace().catch(() => false)
      this.spaceLoading = false
      if (res === false) return

      let data = res.data || []
      data = flatList2tree(data, { id: 'spaceId' })
      data = removeEmptyArray(data)
      this.spaceTree = data
    },
    onChangeSpaceId(item = {}) {
      this.form.spaceName = item.spaceName
    },
    // 打开选择图片文件
    openSelectFileList() {
      const opt = {
        taskId: this.prjchkId,
        chkitemType: this.chkitemType,
        chkitemCode: this.form.chkitemCode || this.firChkList[0]?.chkitemCode || '',
        firChkList: this.firChkList
      }
      this.$refs.SelectFileList.open(opt)
    },
    // 选择图片文件回调
    onSelectFileList(selected) {
      const { prjchkId } = this
      selected.map(i => {
        i.bizId = prjchkId
        i.category = 'cqEvalProblem'
        i.type = 'jpeg'
      })

      const list = this.picList
      const idMap = list.reduce((o, i) => !void (o[i.fileId] = 1) && o, {})
      const list2 = selected.filter(i => !idMap[i.fileId])
      if (!list2.length) return

      this.picList = list.concat(list2)
    },
    previewPic(item) {
      // 预览大图
      this.previewSrcList = this.picList.map(i => i.url)
      this.previewSrc = item.url
      this.$nextTick(() => this.$refs.previewRef?.clickHandler())
      return
    },
    async submit() {
      const valid = await this.$refs.form.validate().catch(() => false)
      if (!valid) return false

      const data = JSON.parse(JSON.stringify(this.form))
      // 非交付时，为默认值 NORMAL
      if (!this.isDelivery) data.problemType = 'NORMAL'
      if (!data.positionId) data.positionName = ''
      if (!data.violateNum) data.violateNum = '0'
      data.picList = this.picList

      return data
    }
  }
}
</script>
<style lang="scss" scoped>
.pic-list {
  display: flex;
  flex-wrap: wrap;
  .item {
    display: flex;
    justify-content: center;
    align-items: center;
    width: 64px;
    height: 64px;
    border-radius: 4px;
    border: 1px solid #c0ccda;
    box-sizing: border-box;
    overflow: hidden;
    color: #8c939d;
    font-size: 32px;
    margin: 0 5px 5px 0;
    cursor: pointer;
  }
  .img {
    width: 100%;
    height: 100%;
  }
}
</style>
